//
//  LastfmTagModuleSource.h
//  LastfmTagModule
//
//  Created by Thomas Backman on 11/21/07.
//  Copyright Thomas Backman 2007. All rights reserved.
//

#import "LastfmTagModuleSource.h"
#import "LastfmTagModuleAction.h"
#import <QSCore/QSObject.h>

@implementation LastfmTagModuleSource

- (BOOL)objectHasChildren:(QSObject *)object {
	// All types we have are supposed to have children, so:
	return YES;
}

- (BOOL)loadChildrenForObject:(QSObject *)object  {
	// "Last.fm tag" object, should simply have all last.fm tags as its children
	if ([[object primaryType] isEqualToString:LastfmTagModuleGroupType]) {
		[object setChildren: [self objectsForEntry:nil]];
		return YES;
	}
	
	// If we get here, the user arrowed in to a specific tag.

	NSMutableArray *taggedTracks = [[QSReg getClassInstance:@"LastfmTagModuleAction"] fetchTracksForTag:[object stringValue]];
	NSMutableArray *children = [NSMutableArray array];
	NSArray *matchedTracks;
	for (TBSong *song in taggedTracks) {
		// Loop through all tagged with this tag
		matchedTracks = [[QSReg getClassInstance:@"LastfmTagModuleAction"] iTunesDictionariesForTrack:[song songTitle] byArtist:[song artist]];
		for (NSDictionary *track in matchedTracks) {
			// We loop through the matched, to make sure we get "duplicates" from different albums (and don't accidentally leave a track out)
			QSObject *trackObject = [[QSReg getClassInstance:@"QSiTunesObjectSource"] trackObjectForInfo:track inPlaylist:nil];
			if (trackObject != nil) {
				// Found one!
				[children addObject:trackObject];
			}
		}
	}
	
	[object setChildren:children];	
	return YES;
}

- (BOOL)indexIsValidFromDate:(NSDate *)indexDate forEntry:(NSDictionary *)theEntry
{
	int num = [[NSUserDefaults standardUserDefaults] integerForKey:@"Last.fm update freq"] * 3600;
	
	if (num == 0) {
		 // just in case something odd happens
		NSLog(@"Warning, hard-coded default value used for update delay (standardUserDefaults returned 0)");
 		num = 7200;
	}
	
	NSLog(@"LastFmTagModule: Update interval set to %d secs", num);
	
	if ([indexDate timeIntervalSinceNow] < -num) {
		indexDate = [NSDate date]; // probably not needed
		NSLog(@"Updating cached copy of tags.xml");
		return NO;
	}
	else {
		NSLog(@"Cached copy still valid, not updating");
		return YES;
	}
}

- (NSArray *) objectsForEntry:(NSDictionary *)theEntry
{
	// FIXME: Are we online?
	// initWithContentsOfURL seems to time out instantly otherwise,
	// so this might not need fixing
	
	NSString *username = [[NSUserDefaults standardUserDefaults] stringForKey:@"Last.fm username"];
	if (username == nil || [username isEqualToString:@"YourUsername"]) {
		[[NSAlert alertWithMessageText:@"Unable to read your username! Did you actually change the default setting?" defaultButton:@"Hmm, OK" alternateButton:nil otherButton:nil informativeTextWithFormat:nil] 
		 runModal];
		return nil;
	}
	NSError *err;
	
	NSString *urlString = [NSString stringWithFormat:@"http://ws.audioscrobbler.com/1.0/user/%@/tags.xml", username];
	
	// Fetch the XML document
	NSXMLDocument *xmlDocument = [[NSXMLDocument alloc] initWithContentsOfURL:[[NSURL alloc] initWithString:urlString] options:NSXMLDocumentTidyXML error:&err];
	if (err != nil) {
		NSString *errText = [err localizedDescription];
		[[NSAlert alertWithMessageText:@"An error occured while downloading or parsing the tags XML file. Raw error message:" 
						 defaultButton:@"OK :(" alternateButton:nil otherButton:nil informativeTextWithFormat:errText]
		 runModal];
		if (xmlDocument) 
			[xmlDocument release];
		return nil;
	}
	
	if (!xmlDocument) {
		return nil;
	}
	
	NSMutableArray *tagList = [NSMutableArray array];

	for (NSXMLNode *tag in [xmlDocument nodesForXPath:@"./toptags/tag/name" error:&err]) {
		// Extract all tag names
		[tagList addObject:[tag stringValue]];
	}
	
	[xmlDocument release];
	
    NSMutableArray *objects = [[NSMutableArray alloc] initWithCapacity:[tagList count]];
    QSObject *newObject;
	
	NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:[[NSWorkspace sharedWorkspace] fullPathForApplication:@"iTunes.app"]];	
	
	for (NSString *currentTag in tagList) {
		// Loop through all tags and add them to the array
		newObject =[QSObject objectWithName:currentTag];
		[newObject setObject:currentTag forType:LastfmTagModuleType];
		[newObject setPrimaryType:LastfmTagModuleType];
		
		[newObject setIcon: icon];
		[objects addObject:newObject];
	}
	
	// Create the "meta-object", that contains all tags
	newObject =[QSObject objectWithString:@"Last.fm tag"];
	[newObject setObject:@"Last.fm tag" forType:LastfmTagModuleGroupType];
	[newObject setPrimaryType:LastfmTagModuleGroupType];
	[newObject setIcon: icon];
	[objects addObject:newObject];
	
    return [objects autorelease];
}

- (void)setQuickIconForObject:(QSObject *)object {
	[object setIcon: [[NSWorkspace sharedWorkspace] iconForFile:[[NSWorkspace sharedWorkspace] fullPathForApplication:@"iTunes.app"]]];	
}

- (BOOL)loadIconForObject:(QSObject *)object {
	return YES;
}

@end
